package cn.lili.modules.promotion.serviceimpl;

import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.promotion.entity.dos.GreenCommonwealContribution;
import cn.lili.modules.promotion.entity.dos.GreenProject;
import cn.lili.modules.promotion.entity.enums.GreenProjectStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum;
import cn.lili.modules.promotion.mapper.GreenCommonwealContributionMapper;
import cn.lili.modules.promotion.mapper.GreenProjectMapper;
import cn.lili.modules.promotion.service.GreenCommonwealContributionService;
import cn.lili.modules.promotion.service.GreenProjectService;
import cn.lili.mybatis.util.PageUtil;
import com.api.PayApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.pojos.AppBalance;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class GreenProjectServiceImpl extends ServiceImpl<GreenProjectMapper, GreenProject>
        implements GreenProjectService {

    private final PayApi payApi;

    @Resource
    private GreenCommonwealContributionMapper greenCommonwealContributionMapper;

    /**
     * 分页查询绿色公益项目
     * @param greenProject
     * @param pageVO
     * @return
     */
    @Override
    public Page<GreenProject> getByPage (GreenProject greenProject, PageVO pageVO) {
        LambdaQueryWrapper<GreenProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(greenProject.getProjectTitle()), GreenProject::getProjectTitle, greenProject.getProjectTitle());
        queryWrapper.eq(null != greenProject.getStatus(), GreenProject::getStatus, greenProject.getStatus());
        queryWrapper.ge(null != greenProject.getStartTime(), GreenProject::getStartTime, greenProject.getStartTime());
        queryWrapper.le(null != greenProject.getEndTime(), GreenProject::getEndTime, greenProject.getEndTime());
        queryWrapper.eq(GreenProject::getDeleteFlag, false);
        queryWrapper.orderByDesc(GreenProject::getCreateTime);
        return this.baseMapper.selectPage(PageUtil.initPage(pageVO), queryWrapper);
    }

    /**
     * 添加绿色公益项目
     * @param greenProject
     */
    @Override
    public void addProject (GreenProject greenProject) {
        if (StringUtils.isEmpty(greenProject.getProjectTitle())
                || null == greenProject.getStartTime()
                || null == greenProject.getEndTime()
                || StringUtils.isEmpty(greenProject.getProjectPicture())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }
        greenProject.setContributionMoney(greenProject.getContributionMoney().multiply(new BigDecimal("100")));
        greenProject.setStatus(getProjectStatus(greenProject.getStartTime(), greenProject.getEndTime()));
        greenProject.setId(SnowFlake.getIdStr());

        GreenCommonwealContribution contribution = new GreenCommonwealContribution();
        contribution.setContributionMoney(greenProject.getContributionMoney());
        contribution.setContributionType(0);
        contribution.setStatus(1);
        contribution.setRemarks(greenProject.getProjectTitle() + "，捐赠公益资金");
        contribution.setOpenId("-1");
        contribution.setUserId("-1");
        greenCommonwealContributionMapper.insert(contribution);

        if (GreenProjectStatusEnum.START.name().equals(greenProject.getStatus())) {
            LambdaUpdateWrapper<GreenProject> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(GreenProject::getStatus, GreenProjectStatusEnum.START.name());
            updateWrapper.set(GreenProject::getStatus, GreenProjectStatusEnum.CLOSE.name());
            this.update(updateWrapper);
        }

        String attach = greenProject.getProjectTitle() + ",捐赠公益项目资金";
        if (payApi.paymentFromApp("fy_ds7d8s9a1031", "a78s9dd78s9ads1031", attach,
                greenProject.getContributionMoney().stripTrailingZeros().toPlainString(),
                "GMONEY")) {
            this.save(greenProject);
        }
    }

    /**
     * 编辑绿色公益项目
     * @param greenProject
     */
    @Override
    public void editProject (GreenProject greenProject) {
        if (StringUtils.isEmpty(greenProject.getProjectTitle())
                || null == greenProject.getStartTime()
                || null == greenProject.getEndTime()
                || StringUtils.isEmpty(greenProject.getProjectPicture())
                || StringUtils.isEmpty(greenProject.getId())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }
        greenProject.setStatus(getProjectStatus(greenProject.getStartTime(), greenProject.getEndTime()));
        this.updateById(greenProject);
    }

    /**
     * 编辑项目状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus (String id, String status) {
        if (StringUtils.isEmpty(id)
                || StringUtils.isEmpty(status)) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }
        GreenProject greenProject = this.getById(id);
        if (null == greenProject) {
            throw new ServiceException("公益项目不存在");
        }
        greenProject.setStatus(status);
        this.updateById(greenProject);
    }

    /**
     * @return 项目状态
     * @see cn.lili.modules.promotion.entity.enums.GreenProjectStatusEnum
     */
    public String getProjectStatus(Date startTime, Date endTime) {
        if (endTime == null) {
            return startTime != null ? GreenProjectStatusEnum.START.name() : GreenProjectStatusEnum.CLOSE.name();
        }
        Date now = new Date();
        if (now.before(startTime)) {
            return GreenProjectStatusEnum.NEW.name();
        } else if (endTime.before(now)) {
            return GreenProjectStatusEnum.END.name();
        } else if (now.before(endTime)) {
            return GreenProjectStatusEnum.START.name();
        }
        return GreenProjectStatusEnum.CLOSE.name();
    }

    /**
     * 获取最新公益项目
     * @return
     */
    @Override
    public GreenProject getByLast () {
        LambdaQueryWrapper<GreenProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GreenProject::getDeleteFlag, false);
        queryWrapper.orderByDesc(GreenProject::getCreateTime);
        queryWrapper.last("limit 1");
        return this.baseMapper.selectOne(queryWrapper);
    }

    /**
     * 获取绿色公益账户余额
     * @return
     */
    @Override
    public BigDecimal getBalance() {
        AppBalance appBalance = payApi.getAppBalance("fy_ds7d8s9a1031");
        if (null != appBalance) {
            return appBalance.getGmoney();
        }
        return null;
    }

    /**
     * 分页获取公益捐赠项目
     * @param pageVO
     * @return
     */
    @Override
    public Map<String, Object> getPageByAll (PageVO pageVO) {
        Map<String, Object> resultMap = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        LambdaQueryWrapper<GreenProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GreenProject::getDeleteFlag, false);
        queryWrapper.orderByDesc(GreenProject::getCreateTime);
        Page<GreenProject> page = this.page(PageUtil.initPage(pageVO), queryWrapper);
        if (!page.getRecords().isEmpty()) {
            page.getRecords().forEach(greenProject -> {
                greenProject.setCreateDate(sdf.format(greenProject.getCreateTime()));
            });
            Map<String, List<GreenProject>> map = page.getRecords().stream().collect(Collectors.groupingBy(GreenProject::getCreateDate));
            Map<String, List<GreenProject>> result1 = sortByKey(map, true);
            resultMap.put("count", page.getTotal());
            resultMap.put("data", result1);
        }else {
            resultMap.put("data", new HashMap<>());
        }
        return resultMap;
    }

    /**
     * 根据map的key排序
     *
     * @param map 待排序的map
     * @param isDesc 是否降序，true：降序，false：升序
     * @return 排序好的map
     */
    @Override
    public <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
        Map<K, V> result = Maps.newLinkedHashMap();
        if (isDesc) {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        } else {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        }
        return result;
    }


    /**
     * 更新绿色公益项目
     */
    @Override
    public void updateGreenProjectStatus() {
        LambdaUpdateWrapper<GreenProject> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.le(GreenProject::getEndTime, new Date());
        updateWrapper.eq(GreenProject::getStatus, GreenProjectStatusEnum.START.name());
        updateWrapper.set(GreenProject::getStatus, GreenProjectStatusEnum.END.name());
        this.update(updateWrapper);
    }

}
